package com.example.demo.zk;


import org.apache.logging.log4j.Logger;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 基于redis的分布式锁服务
 * Created by hztanghaijiang on 2017/8/24.
 */
@Service("redisDistributedLockService")
public class RedisDistributedLockServiceImpl implements DistributedLockService {

    private static RedissonClient redisson = RedissonManager.getRedisson();
    private static final String LOCK_TITLE = "redisLock_";

    private final static long EXPIRE_SECOND = 1000L;

    private static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(RedisDistributedLockServiceImpl.class);


    @Override
    public boolean lock(String lockName, long waitTime) {
        try {

            RLock lock = redisson.getLock(lockName);
            boolean res = lock.tryLock(waitTime, EXPIRE_SECOND, TimeUnit.MILLISECONDS);
            return res;
//            RSemaphore semaphore = redisson.getSemaphore(lockName);
//            if(semaphore.isExists()){
//                semaphore.tryAcquireAsync(1,EXPIRE_SECOND,TimeUnit.MILLISECONDS);
//            }
//            if (semaphore.isExists()) {
//                return semaphore.tryAcquire();
//            } else {
//                semaphore.trySetPermits(1);
//                semaphore.expire(waitTime, TimeUnit.MILLISECONDS);
//                return semaphore.tryAcquire();
//            }
        } catch (Exception e) {
            log.error("redis exception = " + e.getMessage(), e);
            return false;
        }

    }

    @Override
    public boolean lock(String lockName) {
        return lock(lockName, EXPIRE_SECOND);
    }

    @Override
    public void unLock(String lockName) {
        try {
//            RSemaphore semaphore = redisson.getSemaphore(lockName);
//            if (semaphore.isExists()) {
//                semaphore.release();
//            }
            RLock lock = redisson.getLock(lockName);
            if(lock.isExists()){
                lock.unlock();
            }
        } catch (Exception e) {
            log.error("redis exception = " + e.getMessage(), e);
        }

    }

    public RedissonClient getRedisson() {
        return redisson;
    }

    public void setRedisson(RedissonClient redisson) {
        this.redisson = redisson;
    }
}
